﻿using Engine.FileFormats3D.WR2TerrainLoader.Misc;
using Engine.Graphics;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace Scenario_Editor.Exporter
{
    public class StKit2Workfile
    {
        #region Public Methods

        public static void Export(string filename, Dictionary<string, TexturePropertie> textureProperties, MaterialManager materialManager, Engine.FileFormats3D.WR2TerrainLoader.QADFile qadFile)
        {
            try
            {
                int currentMaterial = 0;
                FileStream fs = new FileStream(filename, FileMode.Create);
                BinaryWriter bw = new BinaryWriter(fs);

                Dictionary<string, TexturePropertie>.ValueCollection texturePropertiesl = textureProperties.Values;
                List<string> texturePropterties = new List<string>(texturePropertiesl.Count);
                List<string> materialtextureName1 = new List<string>(materialManager.GetNumberOfMaterials());
                List<string> materialtextureName2 = new List<string>(materialManager.GetNumberOfMaterials());
                List<string> materialtextureName3 = new List<string>(materialManager.GetNumberOfMaterials());

                for (int i = 0; i < materialManager.GetNumberOfMaterials(); i++)
                {
                    if (materialManager.GetMaterial(i).RegisteredMeshes.Count == 0)
                        continue;

                    materialtextureName1.Add(materialManager.GetMaterial(i).TextureName1.ToUpper());
                    materialtextureName2.Add(materialManager.GetMaterial(i).TextureName2.ToUpper());
                    materialtextureName3.Add(materialManager.GetMaterial(i).TextureName3.ToUpper());
                }

                for (int i = 0; i < texturePropertiesl.Count; i++)
                {
                    texturePropterties.Add(texturePropertiesl.ElementAt(i).TextureName.ToUpper());
                }

                bw.Write("MATNAM".ToCharArray());
                char[] materialName = new char[32];
                bw.Write(materialtextureName1.Count);

                for (int i = 0; i < materialtextureName1.Count; i++)
                {
                    currentMaterial++;
                    materialName.Initialize();
                    string name = string.Format("Material{0}", currentMaterial);
                    name.CopyTo(0, materialName, 0, name.Length);
                    bw.Write(materialName);
                }

                bw.Write("LIGHTS".ToCharArray());
                bw.Write((short)0);

                bw.Write("AMBLIT".ToCharArray());
                bw.Write((byte)0x81);
                bw.Write((byte)0x81);
                bw.Write((byte)0x81);
                bw.Write((byte)0x00);

                bw.Write("MATENL".ToCharArray());
                bw.Write(materialtextureName1.Count);

                for (int i = 0; i < materialtextureName1.Count; i++)
                {
                    bool enlite = false;
                    for (int j = 0; j < texturePropertiesl.Count; j++)
                    {
                        if (texturePropterties[j] == materialtextureName1[i] ||
                            texturePropterties[j] == materialtextureName2[i] ||
                            texturePropterties[j] == materialtextureName3[i])
                        {
                            if (!enlite)
                            {
                                enlite = texturePropertiesl.ElementAt(j).Enlite;
                                if (enlite)
                                    break;
                            }
                        }
                    }
                    bw.Write(enlite);
                }

                bw.Write("MATGRS".ToCharArray());
                bw.Write(qadFile.Surfaces.Count);
                materialtextureName1.Clear();
                materialtextureName2.Clear();
                materialtextureName3.Clear();

                for (int i = 0; i < qadFile.Surfaces.Count; i++)
                {
                    materialtextureName1.Add(qadFile.TextureNames[qadFile.Surfaces[i].texture1ID].ToString().ToUpper());
                    materialtextureName2.Add(qadFile.TextureNames[qadFile.Surfaces[i].texture2ID].ToString().ToUpper());
                    materialtextureName3.Add(qadFile.TextureNames[qadFile.Surfaces[i].texture3ID].ToString().ToUpper());
                }

                for (int i = 0; i < qadFile.Surfaces.Count; i++)
                {
                    bool hasGrasTex1 = false;
                    for (int j = 0; j < textureProperties.Count; j++)
                    {
                        if (texturePropterties[j] == materialtextureName1[i] ||
                            texturePropterties[j] == materialtextureName2[i] ||
                            texturePropterties[j] == materialtextureName3[i])
                        {
                            if (!hasGrasTex1)
                            {
                                hasGrasTex1 = texturePropertiesl.ElementAt(j).HasGras;
                                if (hasGrasTex1)
                                    break;
                            }
                        }
                    }
                    bw.Write(hasGrasTex1);
                }

                bw.Write("MATNSH".ToCharArray()); // No Shadow
                bw.Write(materialtextureName1.Count);

                for (int i = 0; i < materialtextureName1.Count; i++)
                {
                    bool hasNoShadow = false;
                    bw.Write(hasNoShadow);
                }

                bw.Write("GRSCOL".ToCharArray()); // Gras Color
                bw.Write((byte)0x81);
                bw.Write((byte)0x81);
                bw.Write((byte)0x81);
                bw.Write((byte)0x00);

                // Get the number of used Textures.
                List<string> textureNames = new List<string>();

                foreach (var item in qadFile.TextureNames)
                {
                    //if (!textureNames.Contains(item.ToString()))
                    textureNames.Add(item.ToString());
                }

                bw.Write("TEXGRS".ToCharArray());
                bw.Write(textureNames.Count);

                for (int i = 0; i < textureNames.Count; i++)
                {
                    for (int j = 0; j < textureProperties.Count; j++)
                    {
                        if (textureNames[i].ToUpper() == texturePropertiesl.ElementAt(j).TextureName.ToUpper())
                        {
                            bw.Write(texturePropertiesl.ElementAt(j).HasGras);
                            break;
                        }
                    }
                    //bw.Write(false);
                }

                bw.Write("SNWSNI".ToCharArray());
                bw.Write(0);
                bw.Write("LSTTRK".ToCharArray()); // Las Track
                bw.Write(0);
                bw.Write("LWOSRC".ToCharArray());
                bw.Write(0);
                bw.Write("MAKTRK".ToCharArray());
                bw.Write(0);

                bw.Close();
                fs.Close();
            }
            catch (System.Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }

        #endregion Public Methods
    }
}